{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 去除阴影尝试\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "import cv2\n",
    "\n",
    "image = cv2.imread(\"../test_images/1.jpg\")\n",
    "gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n",
    "\n",
    "# 光滑\n",
    "gray = cv2.GaussianBlur(gray, (7, 7), 0)\n",
    "\n",
    " # 闭运算\n",
    "kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))\n",
    "close = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel, iterations=9)\n",
    "\n",
    "# 闭运算结果减去原灰度图像\n",
    "subtracted = cv2.subtract(close, gray)\n",
    "# 取反\n",
    "inverted = cv2.bitwise_not(subtracted)\n",
    "# 归一化\n",
    "normalized = cv2.normalize(inverted, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)\n",
    "\n",
    "edge = cv2.Canny(normalized, 50, 100)  # Canny方法边缘检测\n",
    "\n",
    "contour = image.copy()\n",
    "(cnts, _) = cv2.findContours(edge, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 轮廓检测\n",
    "cv2.drawContours(contour, cnts, -1, (0, 255, 0), 2)  # 绘制轮廓\n",
    "\n",
    "plt.figure(2)\n",
    "plt.imshow(inverted, cmap='gray')\n",
    "plt.figure(3)\n",
    "plt.imshow(edge, cmap='gray')\n",
    "plt.figure(4)\n",
    "plt.imshow(cv2.cvtColor(contour, cv2.COLOR_BGR2RGB))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 二值化尝试\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "import cv2\n",
    "\n",
    "# 二值化\n",
    "# ret, binary = cv2.threshold(normalized, 150, 255, cv2.THRESH_BINARY)\n",
    "\n",
    "# ret, binary = cv2.threshold(normalized, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)\n",
    "binary = cv2.adaptiveThreshold(normalized, 255, \n",
    "                                        cv2.ADAPTIVE_THRESH_GAUSSIAN_C, \n",
    "                                        cv2.THRESH_BINARY_INV, 91, 6)\n",
    "\n",
    "# 闭运算\n",
    "kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))\n",
    "kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))\n",
    "erode = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel1, iterations=3)\n",
    "dilate = cv2.morphologyEx(erode, cv2.MORPH_CLOSE, kernel2, iterations=5)\n",
    "\n",
    "plt.figure(1)\n",
    "plt.imshow(binary, cmap='gray')\n",
    "plt.figure(2)\n",
    "plt.imshow(erode, cmap='gray')\n",
    "plt.figure(3)\n",
    "plt.imshow(dilate, cmap='gray')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "import cv2\n",
    "\n",
    "count = 0  # 积木个数\n",
    "margin = 10  # 裁剪边距\n",
    "draw_rect = image.copy()\n",
    "for i, contour in enumerate(cnts):\n",
    "    area = cv2.contourArea(contour)  # 计算包围形状的面积\n",
    "    if area < 25:  # 过滤面积小于某个值的形状\n",
    "        continue\n",
    "    # print(area)\n",
    "    rect = cv2.minAreaRect(contour)  # 检测轮廓最小外接矩形，得到最小外接矩形的中心(x,y), (宽,高), 旋转角度\n",
    "    box = np.intp(cv2.boxPoints(rect))  # 获取最小外接矩形的4个顶点坐标\n",
    "    cv2.drawContours(draw_rect, [box], 0, (255, 0, 0), 2)  # 绘制轮廓最小外接矩形\n",
    "\n",
    "    h, w = image.shape[:2]  # 原图像的高和宽\n",
    "    rect_w, rect_h = int(rect[1][0]) + 1, int(rect[1][1]) + 1  # 最小外接矩形的宽和高\n",
    "    if rect_w <= 100 or rect_h <= 150:\n",
    "        continue\n",
    "    count += 1\n",
    "    if rect_w <= rect_h:\n",
    "        x, y = int(box[1][0]), int(box[1][1])  # 旋转中心\n",
    "        M2 = cv2.getRotationMatrix2D((x, y), rect[2], 1)\n",
    "        rotated_image = cv2.warpAffine(image, M2, (w * 2, h * 2))\n",
    "        y1, y2 = y - margin if y - margin > 0 else 0, y + rect_h + margin + 1\n",
    "        x1, x2 = x - margin if x - margin > 0 else 0, x + rect_w + margin + 1\n",
    "        rotated_canvas = rotated_image[y1: y2, x1: x2]\n",
    "    else:\n",
    "        x, y = int(box[2][0]), int(box[2][1])  # 旋转中心\n",
    "        M2 = cv2.getRotationMatrix2D((x, y), rect[2] + 90, 1)\n",
    "        rotated_image = cv2.warpAffine(image, M2, (w * 2, h * 2))\n",
    "        y1, y2 = y - margin if y - margin > 0 else 0, y + rect_w + margin + 1\n",
    "        x1, x2 = x - margin if x - margin > 0 else 0, x + rect_h + margin + 1\n",
    "        rotated_canvas = rotated_image[y1: y2, x1: x2]\n",
    "\n",
    "plt.figure(1)\n",
    "plt.imshow(cv2.cvtColor(draw_rect, cv2.COLOR_BGR2RGB))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
